package com.ttbj.controller.costsharing;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.reflect.TypeToken;
import com.ttbj.api.costsharing.CostSharingService;
import com.ttbj.api.dto.CostSharingDto;
import com.ttbj.api.dto.CutPayCostDto;
import com.ttbj.api.dto.Page;
import com.ttbj.api.dto.SettleTotalData;
import com.ttbj.api.exception.BusinessException;
import com.ttbj.api.yitong.CutPayService;
import com.ttbj.api.yitong.YTFinancialService;
import com.ttbj.core.util.JsonUtil;
import com.ttbj.util.ViewDataUtil;


@Controller
public class CostSharingController {
	
	@Autowired
	private CostSharingService costSharingService;
	@Autowired
	private CutPayService cutPayService;
	@Autowired
	private YTFinancialService ytFinancialService;
	
	private static final Logger logger = LoggerFactory.getLogger(CostSharingController.class);
	
	//分账列表页面
	@RequestMapping("/costsharing/cost_sharing_list.htm")
	public String cost_sharing_list() {
		return "costsharing/cost_sharing_list";
	}
	
	//分账详情页面
	@RequestMapping("/costsharing/cut_pay_info.htm")
	public String cut_pay_info() {
		return "costsharing/cut_pay_info";
	}
	
	@RequestMapping("/costsharing/day_month_statistics.htm")
	public String day_month_statistics() {
		return "costsharing/day_month_statistics";
	}
	
	
	/**
	 * 分页，条件查询分成信息
	 * @param costSharingDto 分账信息
	 * @param page 分页
	 * @return
	 */
	@RequestMapping(value="/costsharing/getCostSharingInfoByPage.htm", method=RequestMethod.POST, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String getCostSharingInfoByPage(CostSharingDto costSharingDto, Page page) {
		try {
			List<CostSharingDto> costSharingList = this.costSharingService.findCostSharingInfoByPage(costSharingDto, page);
			int count = 0;
			if (null != costSharingList) {
				count = this.costSharingService.findCostSharingInfoByPageCount(costSharingDto);
			}
			return ViewDataUtil.buildSuccessPageJson("查询分成列表成功", costSharingList, count);
		} catch (BusinessException e) {
			return ViewDataUtil.buildFailureJson(e.getErrorCode(), e.getMessage());
		}
	}
	
	
	/**
	 * 通过支付订单号(paymentOrderNo)查询每一个分账的信息
	 * @param paymentOrderNo 支付订单号
	 * @return
	 */
	@RequestMapping(value="/costsharing/getEveryLastCutPayInfo.htm", method=RequestMethod.GET, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String getEveryLastCutPayInfo(@RequestParam String paymentOrderNo, Page page) {
		List<CutPayCostDto> cutPayCostDtos = this.costSharingService.findEveryLastCutPayInfo(paymentOrderNo, page);
		int count = 0;
		if (null != cutPayCostDtos) {
			count = cutPayCostDtos.size();
		}
		return ViewDataUtil.buildSuccessPageJson("每一个分账信息", cutPayCostDtos, count);
	}
	
	/**
	 * 再次分账的接口
	 * 如果返回码为BP001F(待分账余额不足)或BP004F(分账操作过于频繁)或BP005F(分账失败)或S0000F(受理失败)，
	 * 则都能再次分账；如果出现了比如：0|账户不存在或状态异常|BQ001F 这种失败，目前使用人工处理
	 * @param paymentOrderNo 支付订单号(主扫/被扫支付成功后返回的orderId)
	 * @param dataJsonStr 请求分账中data节点的json字符串
	 * @return
	 */
	@RequestMapping(value="/costsharing/againRequestCutPay.htm", method=RequestMethod.POST, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String againRequestCutPay(@RequestParam String paymentOrderNo, @RequestParam String dataJsonStr) throws Exception{
		//执行再次分账的操作
		Map<String, String> map = this.cutPayService.againOrderCutPay(paymentOrderNo, null, dataJsonStr);
		if (null != map) {
			//如果返回S000S，则说明受理成功
			if (map.get("retCode").equals("S0000S")) {
				return ViewDataUtil.buildSuccessJson(map.get("retInfo"));
			}else {
				return ViewDataUtil.buildFailureJson(1, map.get("retInfo"));
			}
		}else {
			return  ViewDataUtil.buildFailureJson(1, "再次分账的时候出现了异常");
		}
	}
	
	/**
	 * 单个或者批量处理分账撤销
	 * @param cutpaycostList 分账撤销需要用到的信息 
	 * @param paymentOrderNo 支付订单号
	 * @return
	 */
	@RequestMapping(value="/costsharing/batchCutPaycpRevoke.htm", method=RequestMethod.POST, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String batchCutPaycpRevoke(@RequestParam String jsonStr, @RequestParam String paymentOrderNo) throws Exception{
		try {
			logger.info("批量分账撤销，接收到的jsonStr：{}", jsonStr);
			logger.info("批量分账撤销，接收到的paymentOrderNo：{}", paymentOrderNo);
			List<CutPayCostDto> cutpaycostList = JsonUtil.jsonToListBean(jsonStr, new TypeToken<ArrayList<CutPayCostDto>>() {}.getType());
			this.costSharingService.batchCpRevoke(cutpaycostList, paymentOrderNo);
			return ViewDataUtil.buildSuccessJson("操作成功");
		} catch (BusinessException e) {
			return ViewDataUtil.buildFailureJson(e.getErrorCode(), e.getMessage());
		}
	}
	
	/**
	 * 分账查询操作
	 * @param transNo 分账订单号（分账系统）
	 * @param accountNo 账户号
	 * @param status 状态值
	 * @return
	 */
	@RequestMapping(value="/costsharing/cutPayCpQuery.htm", method=RequestMethod.POST, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String cutPayCpQuery(@RequestParam String transNo, @RequestParam String accountNo, @RequestParam String status) {
		try {
			CutPayCostDto cutPayCostDto = new CutPayCostDto();
			cutPayCostDto.setOrderNo(transNo);	//设置分账订单号（分账系统订单号）
			cutPayCostDto.setAccountNo(accountNo);	//设置账户号
			//使用分账查询接口进行查询分账状态
			Map<String, String> resultMap = this.ytFinancialService.getYTFinancialResult(cutPayCostDto, 16, "cp_query");
			String resultStatus = resultMap.get("status");	//得到分账查询返回的status值
			if (resultStatus.equals("1")) {
				cutPayCostDto = (CutPayCostDto) JsonUtil.jsonToBean(resultMap.get("data"), "data", CutPayCostDto.class);
				//如果查询的状态值跟页面传来的状态值不相同，则更新数据库里的状态值
				if (!status.equals(cutPayCostDto.getStatus())) {
					//通过transNo更新数据库里的status值
					this.costSharingService.editCutPayCostStatus(cutPayCostDto.getStatus(), transNo);
				}
				return ViewDataUtil.buildSuccessJson("分账查询成功", cutPayCostDto);
			}else {	//返回0，异常，给页面展示异常信息
				String[] str = resultMap.get("data").split("\\|");
				return ViewDataUtil.buildFailureJson(1, str[1]);
			}
		} catch (Exception e) {
			return ViewDataUtil.buildFailureJson(1, "分账查询异常，请联系管理人员");
		}
	}
	
	/**
	 * 易通金服待结算余额查询
	 * @return
	 */
	@RequestMapping(value="/costsharing/getSettleTotalInfo.htm", method=RequestMethod.GET, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String getSettleTotalInfo() {
		try {
			//请求待结算余额查询接口，返回Map<String, String>
			Map<String, String> resultMap = this.ytFinancialService.getYTFinancialResult(null, 20, "settle_total");
			if (resultMap.get("status").equals("1")) {
				SettleTotalData settleTotalData = 
								(SettleTotalData) JsonUtil.jsonToBean(resultMap.get("data"), "data", SettleTotalData.class);
				return ViewDataUtil.buildSuccessJson("待结算余额查询", settleTotalData);
			}else {
				String retInfo = resultMap.get("data").split("\\|")[2];
				return ViewDataUtil.buildFailureJson(1, retInfo);
			}
		} catch (Exception e) {
			return ViewDataUtil.buildFailureJson(1, "调用待结算余额查询出现异常");
		}
	}
	
	/**
	 * 按天清分统计
	 * @param request
	 * @param startDate 开始时间
	 * @param endDate 结束时间
	 * @param type 类型
	 * @param days 过去的天数
	 * @return
	 */
	@RequestMapping(value="/costsharing/getCostSharingDayStatistics.htm", method=RequestMethod.POST, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String getCostSharingDayStatistics(HttpServletRequest request, 
											  @RequestParam(required=false) String startDate, 
											  @RequestParam(required=false) String endDate, 
											  @RequestParam Integer type,
											  @RequestParam(required=false) Integer days) {
		//按天统计的时间格式
		String dayStatisticsFormat = "%Y-%m-%d";
		//如果开始时间为空，则赋值一个初始值，默认当前时间的前30天
		if (null == startDate || StringUtils.isEmpty(startDate.trim())) {
			startDate = getDayOrMonDate("yyyy-MM-dd", Calendar.DATE, days);
		}
		List<CostSharingDto> costSharingList = this.costSharingService.findCostSharingDayOrMonthStatistics(dayStatisticsFormat, startDate, endDate, type);
		return ViewDataUtil.buildSuccessJson("按天清分统计", costSharingList);
	}
	
	
	/**
	 * 按月清分统计
	 * @param request
	 * @param startDate 开始时间
	 * @param endDate 结束时间
	 * @param type 类型
	 * @param months 可选择的月数
	 * @return
	 */
	@RequestMapping(value="/costsharing/getCostSharingMonStatistics.htm", method=RequestMethod.POST, produces={"text/html;charset=UTF-8;","application/json;"})
	@ResponseBody
	public String getCostSharingMonStatistics(HttpServletRequest request, 
											  @RequestParam(required=false) String startDate, 
											  @RequestParam(required=false) String endDate, 
											  @RequestParam Integer type,
											  @RequestParam(required=false) Integer months) {
		//按月统计的时间格式
		String dayStatisticsFormat = "%Y-%m";
		//如果开始时间为空，则赋值一个初始值，默认当前时间的前12个月
		if (null == startDate || StringUtils.isEmpty(startDate.trim())) {
			startDate = getDayOrMonDate("yyyy-MM", Calendar.MONTH, months);
		}
		List<CostSharingDto> costSharingList = this.costSharingService.findCostSharingDayOrMonthStatistics(dayStatisticsFormat, startDate, endDate, type);
		return ViewDataUtil.buildSuccessJson("按月清分统计", costSharingList);
	}
	
	/**
	 * 获取过去多少天或者过去多少月的日期
	 * @param dateFormat 日期格式
	 * @param field 天或月
	 * @param amount 过去的天数或者月数 int类型
	 * @return
	 */
	private String getDayOrMonDate(String dateFormat, int field, int amount) {
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		Calendar c = Calendar.getInstance();
		c.setTime(new Date());
		c.add(field, amount);
		Date date = c.getTime();
		String startDate = format.format(date);
		return startDate;
	}
}
